﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls.WebParts;
using System.ComponentModel;
using Microsoft.SharePoint;
using System.Web.UI.WebControls;
using System.Web.UI;
using TST.SharePoint.Shared;
using TST.WebParts.Shared.WebControls;
using System.Web.UI.HtmlControls;
using Microsoft.SharePoint.Utilities;
using System.Xml.Serialization;
using System.Xml;
using System.Xml.XPath;
using System.IO;
using System.Xml.Xsl;
using System.Web;

namespace TST.WebParts
{
    [ViewStateModeById]
    public class UserInfoFilter : WebPart, IWebEditable, Microsoft.SharePoint.WebPartPages.ITransformableFilterValues, Microsoft.SharePoint.WebPartPages.IDefaultFilterValue
    {
        private Microsoft.SharePoint.WebPartPages.IFilterValues _filterValues;
        private Exception _exception;

        [Browsable(false),
        Personalizable(PersonalizationScope.Shared)]
        public string UserInfoField { get; set; }

        [ConnectionProvider(
        "default value",
        "UniqueIDForUserInfoDefaultValueConnection",
        AllowsMultipleConnections = true)]
        public Microsoft.SharePoint.WebPartPages.IDefaultFilterValue SetDefaultValueConnection()
        {
            return this;
        }

        [ConnectionProvider(
        "filter value",
        "UniqueIDForUserInfoFilterValueConnection",
        AllowsMultipleConnections = true)]
        public Microsoft.SharePoint.WebPartPages.ITransformableFilterValues SetFilterConnection()
        {
            return this;
        }

        [ConnectionConsumer(
            "filter",
            "UniqueIDForUserInfoFilterConsumer",
            AllowsMultipleConnections = false)]
        public void SetFilter(Microsoft.SharePoint.WebPartPages.IFilterValues filterValues)
        {
            _filterValues = filterValues;

            SPList userInfo = SPContext.Current.Web.SiteUserInfoList;
            if (userInfo != null && filterValues != null)
            {
                //EnsureChildControls();
                List<Microsoft.SharePoint.WebPartPages.ConsumerParameter> parameters = new List<Microsoft.SharePoint.WebPartPages.ConsumerParameter>();
                foreach (SPField field in userInfo.Fields)
                {
                    if (!field.Hidden)
                    {
                        parameters.Add(new Microsoft.SharePoint.WebPartPages.ConsumerParameter(
                            field.Title,
                            Microsoft.SharePoint.WebPartPages.ConsumerParameterCapabilities.SupportsEmptyValue |
                            Microsoft.SharePoint.WebPartPages.ConsumerParameterCapabilities.SupportsSingleValue |
                            Microsoft.SharePoint.WebPartPages.ConsumerParameterCapabilities.SupportsMultipleValues |
                            Microsoft.SharePoint.WebPartPages.ConsumerParameterCapabilities.SupportsAllValue));
                    }
                }
                filterValues.SetConsumerParameters(new System.Collections.ObjectModel.ReadOnlyCollection<Microsoft.SharePoint.WebPartPages.ConsumerParameter>(parameters));
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            if (HideWebPart)
            {
                Hidden = true;
                ChromeType = PartChromeType.None;
            }
        }

        private bool HideWebPart
        {
            get
            {
                return base.WebPartManager != null && !base.WebPartManager.DisplayMode.AllowPageDesign;
            }
        }

        protected override void RenderContents(HtmlTextWriter writer)
        {
            base.RenderContents(writer);

            if (string.IsNullOrEmpty(UserInfoField))
            {
                writer.WriteLine(BaseDataWebPart.GetOpenToolPaneText("This webpart is not yet configured", this.ID));
            }
            else
            {
                writer.WriteLine(String.Format("This filter web part sends the value of property '{0}' of the current user to connected web parts.", UserInfoField));
            }
            // Error handling
            if (_exception != null)
            {
                writer.WriteLine(string.Format("Error: {0}", _exception.Message));
            }
        }

        #region IWebEditable Members

        EditorPartCollection IWebEditable.CreateEditorParts()
        {
            List<EditorPart> newEditors = new List<EditorPart>();

            EditorPartCollection editors = base.CreateEditorParts();
            foreach (EditorPart part in editors)
                newEditors.Add(part);

            newEditors.Add(new UserInfoFilterEditorPart(this.ID));

            return new EditorPartCollection(newEditors);
        }

        object IWebEditable.WebBrowsableObject
        {
            get { return this; }
        }

        #endregion

        #region IDefaultFilterValue Members

        public string DefaultValue
        {
            get
            {
                return UserValue;
            }
        }

        private String UserValue
        {
            get
            {
                if (String.IsNullOrEmpty(UserInfoField))
                    return null;

                SPList userInfo = SPContext.Current.Web.SiteUserInfoList;
                SPField field = userInfo.Fields.GetFieldByInternalName(UserInfoField);
                if (_filterValues == null || string.IsNullOrEmpty(_filterValues.ParameterName)) // || _filterValues.ParameterValues == null || _filterValues.ParameterValues.Count == 0)
                {
                    SPListItem userItem = userInfo.Items.GetItemById(SPContext.Current.Web.CurrentUser.ID);
                    if (userItem[UserInfoField] != null)
                    {
                        Field typed = FieldFactory.GetField(field);
                        return typed.GetTypedValueAsString(userItem[UserInfoField]);
                    }
                }
                else
                {
                    if (_filterValues.ParameterValues == null)
                        return null;
                    SPQuery query = new SPQuery();
                    query.ViewFields = string.Format("<FieldRef Name=\"{0}\" />", UserInfoField);
                    String filterValue = String.Empty;
                    foreach (String s in _filterValues.ParameterValues)
                    {
                        if (!String.IsNullOrEmpty(s))
                        {
                            filterValue = s;
                            break;
                        }
                    }
                    if (!String.IsNullOrEmpty(filterValue))
                    {
                        SPField filterField = userInfo.Fields[_filterValues.ParameterName];
                        query.Query = String.Format("<Where><Eq><FieldRef Name='{0}'/><Value Type='Text'>{1}</Value></Eq></Where>", filterField.InternalName, filterValue);
                        SPListItemCollection filteredUsers = userInfo.GetItems(query);
                        if (filteredUsers.Count > 0)
                        {
                            SPListItem userItem = filteredUsers[0];
                            if (userItem[UserInfoField] != null)
                            {
                                Field typed = FieldFactory.GetField(field);
                                return typed.GetTypedValueAsString(userItem[UserInfoField]);
                            }
                        }
                    }
                }
                return null;
            }
        }

        #endregion

        #region ITransformableFilterValues Members

        public bool AllowAllValue
        {
            get { return false; }
        }

        public bool AllowEmptyValue
        {
            get { return false; }
        }

        public bool AllowMultipleValues
        {
            get { return true; }
        }

        public string ParameterName
        {
            get { return "FilterValue"; }
        }

        public System.Collections.ObjectModel.ReadOnlyCollection<string> ParameterValues
        {
            get
            {
                List<string> values = new List<string>();
                String value = UserValue;
                if (!String.IsNullOrEmpty(value))
                {
                    values.Add(value);
                }
                System.Collections.ObjectModel.ReadOnlyCollection<string> result = new System.Collections.ObjectModel.ReadOnlyCollection<string>(values);
                return result;
            }
        }

        #endregion
    }
}
